package org.eenie.appseed.ui.logcat

import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.Utils
import java.io.File
import java.text.SimpleDateFormat
import kotlin.concurrent.thread

object LogcatCollector {


    private var logcatProcess: Process? = null
    private var exitCode = -1
    private var threadLogcat: Thread? = null
    private val logTimestamp = System.currentTimeMillis()
    private var targetDir = Utils.getApp().getExternalFilesDir(null)?.absolutePath ?: Utils.getApp().filesDir.absolutePath
    private val logDirName = "log"
    private val logFileName by lazy {
        genFileName()
    }
    private val logFilePath = targetDir + File.separator + logDirName + File.separator + logFileName
    private val logcatCmd = arrayOf("logcat", "-v", "time", "-f", logFilePath)
    private var isProcessAlive = false
    private var stopByUser = false
    private var logLevel = LogcatLevel.V

    fun start(level: LogcatLevel = LogcatLevel.V) {
        logLevel = level
        if (logcatProcess == null && isProcessAlive) {
            val logFileDir = File(targetDir + File.separator + logDirName)
            if (!logFileDir.exists()) {
                logFileDir.mkdir()
            }
            exitCode = -1
            threadLogcat = thread(name = "logcat") {
                runLogcat()
            }
        } else {
            LogUtils.i(LogcatCollector::class, "logcat collector is running")
        }
    }


    private fun runLogcat() {
        stopByUser = false
        val processBuilder = ProcessBuilder(*logcatCmd, logLevel.cmd)
        runCatching {
            logcatProcess = processBuilder.start()
            LogUtils.i("logcat collector start $exitCode")
            isProcessAlive = true
        }.onFailure {
            it.printStackTrace()
        }
        exitCode = runCatching {
            logcatProcess?.waitFor()
        }.getOrThrow() ?: -1
        isProcessAlive = false

        LogUtils.i("logcat collector exit $exitCode by user = $stopByUser")
        if (!stopByUser) {
            start(logLevel)
        }
    }


    private fun genFileName(): String {
        val formator = SimpleDateFormat("yyyy_MM_dd_HH_mm_ss")
        return "logcat_${formator.format(logTimestamp)}_0.log"
    }


    fun stop() {
        stopByUser = true
        logcatProcess?.destroy()
        logcatProcess = null
        clear()
    }


    fun clear() {
        val cmd = arrayOf("logcat", "-c")
        ProcessBuilder(*cmd).start()
    }

}